package cn.shengongying.utils;


import cn.shengongying.enums.ResponseCodeEnum;
import cn.shengongying.exception.BusinessException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.util.Base64;

/**
 * @author : RXK
 * Date : 2021/6/21 18:44
 * Code Less Think More
 * Desc: 解密工具类
 */
public class DecryptUtils {

    /**
     * 解密微信小程序的用户信息
     *
     * @return ：用户信息字符串
     * {
     * "openId": "OPENID",
     * "nickName": "NICKNAME",
     * "gender": GENDER,
     * "city": "CITY",
     * "province": "PROVINCE",
     * "country": "COUNTRY",
     * "avatarUrl": "AVATARURL",
     * "unionId": "UNIONID",
     * "watermark":
     * {
     * "appid":"APPID",
     * "timestamp":TIMESTAMP
     * }
     * }
     */
    public static String wechatDecrypt(String encryptedData, String iv, String sessionKey) throws BusinessException {
        byte[] encryptedDataByte = Base64.getDecoder()
                                         .decode(encryptedData);
        byte[] ivByte = Base64.getDecoder()
                              .decode(iv);
        byte[] sessionKeyByte = Base64.getDecoder()
                                      .decode(sessionKey);

        try {
            Security.addProvider(new BouncyCastleProvider());

            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec spec = new SecretKeySpec(sessionKeyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
            byte[] resultByte = cipher.doFinal(encryptedDataByte);

            return new String(resultByte, StandardCharsets.UTF_8);
        } catch (NoSuchAlgorithmException | InvalidParameterSpecException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
            throw new BusinessException(ResponseCodeEnum.server_exception.getMsg());
        }
    }

    private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS5Padding";
    public static String wechatOrderDecrypt(String data,String appSecret) throws BusinessException {
        byte[] decode = org.apache.commons.codec.binary.Base64.decodeBase64(data);

        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
            byte[] bytes = MD5.MD5Encode(appSecret)
                              .toLowerCase()
                              .getBytes();
            SecretKeySpec key = new SecretKeySpec(bytes, "AES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] doFinal = cipher.doFinal(decode);
            return new String(doFinal);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
            throw new BusinessException(ResponseCodeEnum.server_exception.getMsg());
        }
    }

    private DecryptUtils() {
    }

}
